#region Header
//********************************************************************
//	author:         Thomas "zeroflag" Kraemer
//	author email:   zeroflag@zeroflag.de
//	
//	Copyright (C) 2006-2007  Thomas "zeroflag" Kraemer
//	
//	license:	(LGPL)
//	
//		This library is free software; you can redistribute it and/or
//		modify it under the terms of the GNU Lesser General Public
//		License as published by the Free Software Foundation; either
//		version 2.1 of the License, or (at your option) any later version.
//
//		This library is distributed in the hope that it will be useful,
//		but WITHOUT ANY WARRANTY; without even the implied warranty of
//		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//		Lesser General Public License for more details.
//
//		You should have received a copy of the GNU Lesser General Public
//		License along with this library; if not, write to the Free Software
//		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
//		http://www.gnu.org/licenses/lgpl.html#TOC1
//
//*********************************************************************
#endregion Header

using System;
using System.Collections.Generic;
using System.Text;

namespace Enyo
{
	public class DataInformationProperty<T> : DataInformationProperty
	{
		private string m_Name;

		/// <summary>
		/// The name of the property.
		/// </summary>
		public override string Name
		{
			get
			{
				if (this.m_Name == null && this.m_Info != null)
					this.m_Name = this.m_Info.Name;
				return m_Name;
			}
			set { m_Name = value; }
		}
		private System.Reflection.PropertyInfo m_Info;

		/// <summary>
		/// The property info object.
		/// </summary>
		protected override System.Reflection.PropertyInfo Info
		{
			get
			{
				if (this.m_Info == null && this.m_Name != null)
				{
					// create property info from name and type...
					this.m_Info = this.Type.GetProperty(this.m_Name);
				}
				return m_Info;
			}
			set { m_Info = value; }
		}

		/// <summary>
		/// The type which contains the property.
		/// </summary>
		public override Type DataType
		{
			get
			{
				return typeof(T);
			}
		}

		/// <summary>
		/// The property's return type.
		/// </summary>
		public override Type Type
		{
			get
			{
				return this.Info.PropertyType;
			}
		}

		public delegate string GetStringHandler(T value, System.Reflection.PropertyInfo info);
		GetStringHandler m_GetStringCallback;
		/// <summary>
		/// A callback to inject an alternate string for the property.
		/// </summary>
		public GetStringHandler GetStringCallback
		{
			get { return m_GetStringCallback; }
			set { m_GetStringCallback = value; }
		}

		public virtual string GetValueString(T value)
		{
			if (value == null)
				return "<null>";
			else if (this.GetStringCallback != null)
				return this.GetStringCallback(value, this.Info);
			else
				return value.ToString();
		}

		public override string GetValueString(object value)
		{
			return this.GetValueString((T)value);
		}
	}

	public abstract class DataInformationProperty
	{
		/// <summary>
		/// The name of the property.
		/// </summary>
		public abstract string Name
		{
			get;
			set;
		}

		/// <summary>
		/// The property info object.
		/// </summary>
		protected abstract System.Reflection.PropertyInfo Info
		{
			get;
			set;
		}

		/// <summary>
		/// The type which contains the property.
		/// </summary>
		public abstract Type DataType
		{
			get;
		}

		/// <summary>
		/// The property's return type.
		/// </summary>
		public abstract Type Type
		{
			get;
		}

		public abstract string GetValueString(object value);
	}
}
